//
//  LANFindServer.m
//  AQ800
//
//  Created by 赵武 on 13-12-10.
//  Copyright (c) 2013年 杭州茂葳科技有限公司. All rights reserved.
//

#import "LANFindServer.h"

@interface LANFindServer()
{
    // 全局变量
    NSUInteger m_port;
    BOOL m_run;
    NSString *m_lock1;
    NSString *m_lock2;
    NSMutableArray *m_lan_dev;
    NSThread *m_ts;
    void (^m_newDeviceCallback)(WifiDevice *obj);
    id m_tag;
}
@end

// 局域网设备发现服务
@implementation LANFindServer

// 初始化
- (id)init
{
    m_port = 15151;
    m_run = NO;
    m_lock1 = @"LANFindServer_lock1";
    m_lock2 = @"LANFindServer_lock2";
    m_lan_dev = nil;
    m_newDeviceCallback = nil;
    return [super init];
}

// 设置回调
- (void)setNewDeviceCallback:(void (^)(WifiDevice *obj))newDevice
{
    m_newDeviceCallback = newDevice;
}

// 获得新设备的处理
- (void) NewDeviceInfo:(WifiDevice *)newDevice
{
    m_newDeviceCallback(newDevice);
}

// 将信息数据包转化为信息体
- (void) PackToInfo:(char *)pack devip:(char *)devip
{
    NSString *ip = [NSString stringWithUTF8String:devip];
    NSString *mac = nil;
    NSString *pass = nil;
    NSString *did = nil;
    char *p1, *p2, *p3, *p4;
    int len;
    
    len = strlen(pack);
    p1 = pack;
    p2 = strchr(pack, '\n');
    if (p2 == NULL)
    {
        return;
    }
    p2[0] = 0x00;
    p2++;
    p3 = strchr(p2, '\n');
    if (p3 == NULL)
    {
        return;
    }
    p3[0] = 0x00;
    p3 ++;
    p3 ++;
    p4 = strchr(p3, '\n');
    if (p4 == NULL)
    {
        return;
    }
    p4[0] = 0x00;
    if (p1[0] == 'm')
    {
        p1++;
        mac = [NSString stringWithUTF8String:p1];
    }
    if (p2[0] == 'p')
    {
        p2++;
        pass = [NSString stringWithUTF8String:p2];
    }
//    if (p3[0] == '\n')
//    {
//        p3++;
//    }
    if (p3[0] == 'u')
    {
        p3++;
        did = [NSString stringWithUTF8String:p3];
    }
    WifiDevice *dev = [[WifiDevice alloc] init];
    [dev defaultParame];
    dev.m_did = did;
    dev.m_lanIp = ip;
    dev.m_mac = mac;
    dev.m_password = pass;
    if (m_newDeviceCallback != nil)
    {
        [self performSelectorOnMainThread:@selector(NewDeviceInfo:) withObject:dev waitUntilDone:YES];
    }
}

// 发送线程
- (void)ts_run
{
    
    @synchronized(m_lock1)
    {
        int sin_len;
        int udp = -1;
        char message[2048];
        struct sockaddr_in sin;
        
        bzero(&sin, sizeof(sin));
        sin.sin_family=AF_INET;
        sin.sin_addr.s_addr=htonl(INADDR_ANY);
        sin.sin_port=htons(m_port);
        sin_len = sizeof(sin);
        
        int bl = 0;
        udp = socket(AF_INET, SOCK_DGRAM, 0);
        bl = bind(udp, (struct sockaddr *)&sin, sizeof(sin));
        int value = 1;
        setsockopt(udp, SOL_SOCKET, SO_BROADCAST, (const void *)&value, sizeof(value));
        struct sockaddr_in address;     //处理网络通信的地址
        
        bzero(&address,sizeof(address));
        address.sin_family=AF_INET;
        address.sin_addr.s_addr=htonl(INADDR_BROADCAST);    //这里不一样
        address.sin_port=htons(m_port);
        
        // 发送两条探测信息
        bl = sendto(udp, "12345", 5,0,(struct sockaddr *)&address,sizeof(address));
        bl = sendto(udp, "12345", 5,0,(struct sockaddr *)&address,sizeof(address));
        // 监听广播包
        fd_set rfd;
        struct timeval tv;
        int len, ret, i;
        char devip[64];
        FD_ZERO(&rfd);
        while(![m_ts isCancelled])
        {
            usleep(1000);
            tv.tv_sec = 0;
            tv.tv_usec = 100000;
            FD_SET(udp, &rfd);
            ret = select(udp+1, &rfd, NULL, NULL, &tv);
            if (ret == 0)
            {
                continue;
            }
            if (FD_ISSET(udp, &rfd))
            {
                bl = recvfrom(udp, message, sizeof(message), 0, (struct sockaddr *)&sin, (socklen_t *)&sin_len);
                if (bl == 0)
                {
                    break;
                }
                if (bl > 0)
                {
                    //NSLog(@"bl = %d, sin_len = %d", bl, sin_len);
                    // 校验数据
                    len = bl;
                    if (len<2)
                    {
                        continue;
                    }
                    for (i=0; i<len; i++)
                    {
                        message[i] ^= 0xa5;
                    }
                    int sum1 = 0;
                    int sum2 = 0;
                    for (i=0; i<(len-2); i++)
                    {
                        sum1 += message[i];
                    }
                    sum1 &= 0xffff;
                    sum2 = message[len-2];
                    sum2 <<= 8;
                    sum2 &= 0xff00;
                    sum2 |= message[len-1] & 0x00ff;
                    if (sum1 == sum2)
                    {
                        inet_ntop(AF_INET, (void *)&sin.sin_addr, devip, sin_len);
                        // 校验通过，开始解码数据包
                        message[len-2] = 0x00;
                        [self PackToInfo:message devip:devip];
                    }
                }
            }
        }
        // 关闭udp
        close(udp);
        NSLog(@"局域网发现功能线程退出");
    }
}

// 开始监听去发现新设备
- (BOOL) Start
{
    [self Stop];
    @synchronized(m_lock1)
    {
        m_ts = [[NSThread alloc] initWithTarget:self selector:@selector(ts_run) object:nil];
    }
    [m_ts start];
    return YES;
}

// 停止监听设备
- (BOOL) Stop
{
    if ( m_ts != nil )
    {
        [m_ts cancel];
        return YES;
    }
    return NO;
}

@end
